#include "mycomponent.h"


Song* PlayList::playNext()
{
    if(size <= 0)
        return nullptr;

    if(mode == RandomPlay)
    {
        if(cur+1 >= size)
        {
            Random(0, size - 1);
            cur = 0;
            return vec[cur];
        }
        return vec[++cur];
    }
    else
    {
        if(cur_node->next == dump)
        {
            cur_node = dump->next;
        }
        else
        {
            cur_node = cur_node->next;
        }
        return cur_node->data;
    }
}

Song* PlayList::playPre()
{
    if(size <= 0)
        return nullptr;

    if(mode == RandomPlay)
    {
        cur = (cur - 1 + size) % size;
        return vec[cur];
    }
    else
    {
        if(cur_node->pre == dump)
        {
            cur_node = dump->pre;
        }
        else
        {
            cur_node = cur_node->pre;
        }
        return cur_node->data;
    }
}

//当前歌曲播放完毕时的动作
Song* PlayList::play()
{
    if(size <= 0)
        return nullptr;

    if(mode == RandomPlay)
    {
        return vec[(++cur) % size];
    }
    else if(mode == SinglePlay)
    {
        return cur_node->data;
    }
    else if(mode == OrderPlay)
    {
        if(cur_node->next == dump)
        {
            cur_node = dump->next;
            return nullptr;
        }
        else
        {
            cur_node = cur_node->pre;
            return cur_node->data;
        }
    }
    else if(mode == LoopPlay)
    {

        if(cur_node->pre == dump)
        {
            cur_node = dump->pre;
        }
        else
        {
            cur_node = cur_node->pre;
        }
        return cur_node->data;
    }
    else
        return nullptr;
}

bool PlayList::addNextSong(Song* song, bool isNew)
{
    //新歌曲
    if(isNew)
    {
        ListNode<Song*>* node = new ListNode<Song*>(song, cur_node, cur_node->next);
        QPair<int, ListNode<Song*>*> song_pair = {-1, node};

        //随机歌曲顺序数组的处理
        if(mode == RandomPlay)
        {

            //考虑是不是列表最后一个元素
            if(cur == size - 1)
            {
                vec.push_back(song);
                song_pair.first = size;
            }
            //不是的话
            else
            {
                Song* tmp = vec[cur+1];
                vec.push_back(tmp);
                vec[cur+1] = song;

                QPair<int, ListNode<Song*>*> tmp_pair = song_hash[tmp];
                song_pair.first = cur + 1;
                tmp_pair.first = size;
                song_hash[tmp] = tmp_pair;
            }
        }
        else
        {
            vec.push_back(song);
            song_pair.first = size;
        }

        //环状链表的处理
        cur_node->next = node;
        node->next->pre = node;

        song_hash[song] = song_pair;
        size++;
    }
    //已有歌曲
    else
    {
        QPair<int, ListNode<Song*>*> song_pair = song_hash[song];
        //随机歌曲顺序数组的处理
        if(mode == RandomPlay)
        {
            //不是当前播放或下一首
            if(cur != song_pair.first)
            {
                Song* tmp_song;
                //考虑是不是列表最后一个元素
                if(cur < size - 1)
                {
                    swap(song_pair.first, cur+1);
                }
                //是列表最后一个元素
                else
                {
                    swap(0, cur);
                    swap(1, song_pair.first);
                    cur = 0;
                }
            }
        }
        //不是随机播放随机数组不做处理
        else
        {
            ;
        }

        //环状链表的处理
        ListNode<Song*>* tmp_node = song_pair.second;
        if(cur_node == tmp_node || cur_node->next == tmp_node)
            return true;

        tmp_node->pre->next = tmp_node->next;
        tmp_node->next->pre = tmp_node->pre;

        tmp_node->next = cur_node->next;
        tmp_node->pre = cur_node;

        cur_node->next = tmp_node;
    }

    return true;
}

bool PlayList::addSong(Song* song)
{
    ListNode<Song*>* node = new ListNode<Song*>(song, dump->pre, dump);
    QPair<int, ListNode<Song*>*> song_pair = {-1, node};

    vec.push_back(song);
    song_pair.first = size;

    //环状链表的处理
    dump->pre->next = node;
    dump->pre = node;

    song_hash[song] = song_pair;
    size++;

    return true;
}

bool PlayList::deleteSong(MusicFileInfo *s)
{
    if(size > 0 && song_hash.find(s) != song_hash.end())
    {
        QPair<int, ListNode<Song*>*> song_pair = song_hash[s];
        ListNode<Song*>* node = song_pair.second;

        int pos = song_pair.first;
        song_hash.remove(s);

        //随机歌曲顺序数组的处理
        //不是最后一个元素
        if(pos != size - 1)
        {
            vec[pos] = vec[size - 1];
            QPair<int, ListNode<Song*>*> tmp_pair = song_hash[vec[pos]];
            tmp_pair.first = pos;
            song_hash[vec[pos]] = tmp_pair;
        }

        //环状链表的处理
        node->pre->next = node->next;
        node->next->pre = node->pre;

        delete node;

        size--;
        vec.resize(size);
    }
    return true;
}

bool PlayList::setCurSong(Song* s)
{
    if(song_hash.find(s) == song_hash.end())
        return false;

    QPair<int, ListNode<Song*>*> tmp_pair = song_hash[s];
    cur_node = tmp_pair.second;
    cur = tmp_pair.first;
    return true;
}

bool PlayList::Random(int start, int end)
{
    if(end <= start && end < size)
        return false;
    int bound = end - start + 1;
    for(int i = bound; i > 1; i--)
    {
        int pos = QRandomGenerator::global()->generate() % i + start;
        Song* s = vec[pos];
        int tail = start + i - 1;

        QPair<int, ListNode<Song*>*> tmp_pair1 = song_hash[vec[tail]];
        QPair<int, ListNode<Song*>*> tmp_pair2 = song_hash[s];
        tmp_pair1.first = pos;
        tmp_pair2.first = tail;

        vec[pos] = vec[tail];
        vec[tail] = s;

        song_hash[s] = tmp_pair2;
        song_hash[vec[pos]] = tmp_pair1;
    }

    return true;
}

void PlayList::clear()
{
    vec.clear();
    song_hash.clear();
    ListNode<Song*>* tmp_cur = dump->next;
    ListNode<Song*>* tmp = tmp_cur;
    while(tmp != dump)
    {
        tmp = tmp_cur->next;
        delete tmp_cur;
        tmp_cur = tmp;
    }

    dump->next = dump;
    dump->pre = dump;

    cur_node = dump;

    size = 0;
    cur = 0;
}

void PlayList::swap(int pos1, int pos2)
{
    if(pos1 == pos2)
        return;

    QPair<int, ListNode<Song*>*> tmp_pair1 = song_hash[vec[pos1]];
    QPair<int, ListNode<Song*>*> tmp_pair2 = song_hash[vec[pos2]];

    vec[pos1] = tmp_pair2.second->data;
    vec[pos2] = tmp_pair1.second->data;

    tmp_pair1.first = pos2;
    tmp_pair2.first = pos1;

    song_hash[vec[pos1]] = tmp_pair2;
    song_hash[vec[pos2]] = tmp_pair1;
}
